// 沟通接口
import 'package:common_utils/common_utils.dart' hide LogUtil;
import 'package:flutter/material.dart';
import 'package:orginone/components/Tip/ToastUtils.dart';
import 'package:orginone/dart/base/common/commands.dart';
import 'package:orginone/dart/base/common/emitter.dart';
import 'package:orginone/dart/base/model.dart';
import 'package:orginone/dart/core/chat/activity.dart';
import 'package:orginone/dart/core/chat/session.dart';
import 'package:orginone/dart/core/target/person.dart';
import 'package:orginone/main.dart';
import 'package:orginone/utils/log/log_util.dart';

///沟通起拱器接口
abstract class IChatProvider with EmitterMixin {
  ///会话数据
  late List<ISession> chats;

  /// 沟通未读消息数
  late int noReadChatCount;

  /// 动态处理器
  late IActivityProvider activityProvider;

  ///加载
  Future<void> load({bool reload = false});

  ///唤醒（为了临时处理丢消息问题）
  Future<bool> wakeUp();
}

///沟通起拱器
class ChatProvider with EmitterMixin implements IChatProvider {
  /// 用户信息
  final IPerson user;

  ///会话数据
  @override
  late List<ISession> chats;

  /// 沟通未读消息数
  @override
  late int noReadChatCount;

  /// 动态处理器
  @override
  late IActivityProvider activityProvider;

  /// 是否初始化
  bool _inited = false;

  ChatProvider(this.user) {
    noReadChatCount = 0;
    chats = [];
    activityProvider = ActivityProvider(user, this);
    addDataListener();
  }

  ///添加数据监听
  void addDataListener() {
    //有新会话消息通知
    command.subscribeByFlag('1-session', ([dynamic args]) {
      if (!_inited) return;

      if (args != null && args is List && args.isNotEmpty) {
        var arg = args.first;
        if (arg is Map && arg.containsKey('operate_change')) {
          XLogUtil.d(
              'subscribeByFlag--收到operate_change  ------ ${DateUtil.getNowDateMs()}');
          load(reload: true);
          return;
        }
      }
      //TODO 有新沟通消息通知
      chats = _filterAndSortChats(chats);
      _refreshNoReadMgsCount();
      XLogUtil.dd('>>>>>>ChatProvider.addDataListener.session ${chats.length}');
      _notify();
    });
  }

  void _notify() {
    command.emitter('chat', 'new');
    changeCallback();
  }

  ///加载
  @override
  Future<void> load({bool reload = false}) async {
    try {
      List<ISession> tmpChats = [];
      if (!_inited || reload) {
        tmpChats.addAll(user.chats ?? []);
        for (var company in user.companys ?? []) {
          tmpChats.addAll(company.chats ?? []);
        }
        // for (var element in tmpChats) {
        //   print(
        //       '>>>>>>>>>>>>>>>>>>>>${element.name} ${element.isMyChat} ${(element.chatdata.lastMessage != null || element.chatdata.recently)} ${element.chatdata.lastMessage != null} ${element.chatdata.recently}');
        // }
        chats = _filterAndSortChats(tmpChats);
        _refreshNoReadMgsCount();
        // await activityProvider.load(reload: reload);
        XLogUtil.dd('>>>>>>ChatProvider.load');
        changeCallback();
      }
    } finally {
      _inited = true;
    }
    // wakeUp();
  }

  @override
  Future<bool> wakeUp() async {
    bool hasNewData = false;
    ResultType<Map<String, dynamic>> res =
        await user.cacheObj.load(path: "session");
    if (res.success && null != res.data && res.data!.isNotEmpty) {
      var tmpChats = {};
      var delChats = [];
      await Future.wait(chats.map((e) async {
        tmpChats[e.chatdata.fullId] = e;
        var tmpSession = res.data?[e.chatdata.fullId];
        if (null != tmpSession) {
          if (tmpSession['lastMsgTime'] != e.chatdata.lastMsgTime &&
              tmpSession['lastMsgTime'] > e.chatdata.lastMsgTime) {
            await e.updateMessage(chatData: tmpSession);
            hasNewData = true;
          } else {
            await e.updateMessage(chatData: tmpSession);
          }
        } else {
          delChats.add(e.id);
        }
      }));
      // if (delChats.isNotEmpty) {
      //   chats.removeWhere((element) => delChats.contains(element.id));
      // }
      if (chats.length < res.data!.length) {
        Future.wait(res.data?.entries.map<Future>((e) async {
              if (null == tmpChats[e.key]) {
                // chats.add(value);
                // print('...>>>${e.value['fullId']} ${e.value}');

                if (null != e.value['lastMessage']) {
                  ISession? session = relationCtrl.findMemberChat(
                      e.value['lastMessage']['toId'],
                      e.value['lastMessage']['belongId']);
                  if (null != session) {
                    await session.updateMessage(chatData: e.value);
                    List<ISession> tmpChats = _filterAndSortChats([session]);
                    if (tmpChats.isNotEmpty) {
                      // ToastUtils.showMsg(msg: e.key);
                      chats.add(session);
                      hasNewData = true;
                    }
                  } else {
                    // user.cacheObj
                    //     .set("session_del.${e.value['fullId']}", e)
                    //     .then((value) {
                    //   if (value) {
                    //     user.cacheObj.delete("session.${e.value['fullId']}");
                    //   }
                    // });
                    // print(
                    //     '>>>>>>>>>>>>${value["fullId"]} ${value["lastMessage"]["belongId"]} ${value["lastMessage"]["toId"]}');
                  }
                } else {
                  // user.cacheObj
                  //     .set("session_del.${e.value['fullId']}", e)
                  //     .then((value) {
                  //   if (value) {
                  //     user.cacheObj.delete("session.${e.value['fullId']}");
                  //   }
                  // });
                }
              }
            }) ??
            []);
      }
    } else {
      throw FlutterError("唤醒拉去数据失败:$res");
    }

    if (hasNewData) {
      chats = _filterAndSortChats(chats);
      _refreshNoReadMgsCount();
      // activityProvider.load(reload: true);
      XLogUtil.dd("唤醒：刷新未读数据$noReadChatCount");
      changeCallback();
    } else if (_inited) {
      load();
    }
    XLogUtil.dd('>>>>>>ChatProvider.wakeUp');

    return hasNewData;
  }

  /// 过滤和排序消息
  List<ISession> _filterAndSortChats(List<ISession> sessions) {
    //过滤出最近和有发过消息的会话
    sessions = sessions.where((element) {
      return (element.chatdata.lastMessage != null ||
          element.chatdata.recently);
    }).toList();

    if (sessions.length > 1) {
      /// 排序
      sessions.sort((a, b) {
        var num = 0;
        if (b.chatdata.lastMsgTime == a.chatdata.lastMsgTime) {
          num = b.isBelongPerson ? 1 : -1;
        } else {
          num = b.chatdata.lastMsgTime > a.chatdata.lastMsgTime ? 5 : -5;
        }
        return num;
      });
    }
    return sessions;
  }

  void _refreshNoReadMgsCount() {
    if (chats.isNotEmpty) {
      if (noReadChatCount != 0) {
        noReadChatCount = 0;
      }
      for (var element in chats) {
        if (!element.groupTags.contains("组织群")) {
          noReadChatCount += element.chatdata.noReadCount;
        }
      }
    }
  }
}

///动态提供器接口
abstract class IActivityProvider with EmitterMixin {
  ///群动态
  late GroupActivity cohortActivity;

  ///好友圈
  @Deprecated("和群动态合并")
  late GroupActivity friendsActivity;
  //加载
  Future<void> load({bool reload = false});
}

///动态提供器接口
class ActivityProvider with EmitterMixin implements IActivityProvider {
  final IPerson user;

  ///沟通提供器
  final IChatProvider chatProvider;

  ///群动态
  @override
  late GroupActivity cohortActivity;

  ///好友圈
  @override
  late GroupActivity friendsActivity;
  late bool _inited;
  ActivityProvider(this.user, this.chatProvider) {
    _inited = false;
    cohortActivity = GroupActivity(
      user,
      () {
        return relationCtrl.data.home!.current.activitys;
      },
      true,
    );
    // cohortActivity = GroupActivity(
    //   user,
    //   () {
    //     return chatProvider.chats
    //         .where((i) => i.isMyChat && i.isGroup)
    //         .map((i) => i.activity)
    //         .toList();
    //   },
    //   false,
    // );
    // friendsActivity = GroupActivity(
    //   user,
    //   () {
    //     return [
    //       user.session.activity,
    //       ...user.memberChats.map((i) => i.activity).toList()
    //     ];
    //   },
    //   true,
    // );
  }

  //加载
  @override
  Future<void> load({bool reload = false}) async {
    if (_inited) return;
    _inited = true;
    await cohortActivity.load(reload: reload);
    // await friendsActivity.load(reload: reload);
    changeCallback();
  }
}
